package com.graduation.check.service;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.graduation.check.utils.FileUtil;
import com.graduation.check.entity.PaperExtractionTask;
import com.graduation.check.mapper.PaperExtractionTaskMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

@Slf4j
@Service
public class PaperInfoExtractionService {

    @Autowired
    private AliBailianService aliBailianService;

    @Autowired
    private FileUtil fileUtil;

    @Autowired
    private PaperExtractionTaskMapper paperExtractionTaskMapper;

    private final ObjectMapper objectMapper = new ObjectMapper();

    // 缓存机制，避免重复提取相同内容
    private final Map<String, PaperExtractionResult> extractionCache = new ConcurrentHashMap<>();
    private final Map<String, Long> cacheTimestamps = new ConcurrentHashMap<>();
    private static final long CACHE_EXPIRY_MS = 30 * 60 * 1000; // 30分钟缓存

    // 初始化ObjectMapper配置
    public PaperInfoExtractionService() {
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
    }

    /**
     * 提取论文信息 - 优化版
     */
    public PaperExtractionResult extractPaperInfo(String filePath, String originalFileName, ExtractionOptions options, Long studentId) {
        String cacheKey = generateCacheKey(filePath, options);

        // 检查缓存
        if (isCacheValid(cacheKey)) {
            log.info("使用缓存结果，文件: {}", filePath);
            return extractionCache.get(cacheKey);
        }

        try {
            log.info("开始提取论文信息，文件路径: {}, 原始文件名: {}, 学生ID: {}", filePath, originalFileName, studentId);

            // 从文件中提取文本内容
            String content = fileUtil.extractText(filePath);
            if (content == null || content.trim().isEmpty()) {
                throw new RuntimeException("无法从文件中提取文本内容");
            }

            log.info("成功提取文本内容，长度: {}", content.length());

            // 预处理文本内容
            String processedContent = preprocessContent(content);

            // 构建优化的AI提示词
            String prompt = buildOptimizedExtractionPrompt(processedContent, options);
            log.debug("构建的提示词长度: {}", prompt.length());

            // 调用阿里云百炼API
            String aiResponse = aliBailianService.callQwenModel(prompt);
            log.debug("AI响应接收成功，长度: {}", aiResponse.length());

            // 解析AI响应
            PaperExtractionResult result = parseAIResponse(aiResponse, content);

            // 后处理结果
            result = postProcessResult(result, content, options);

            log.info("论文信息提取完成，基本信息: {}", result.getBasicInfo() != null ? "已提取" : "未提取");

            // 缓存结果
            cacheResult(cacheKey, result);

            // 记录信息提取任务到数据库 - 使用原始文件名
            recordExtractionTask(studentId, filePath, originalFileName, options, result);

            return result;

        } catch (Exception e) {
            log.error("论文信息提取失败: {}", e.getMessage());
            // 使用增强的备用方法
            log.info("使用增强的备用方法提取信息");
            PaperExtractionResult fallbackResult = extractEnhancedFallbackInfo(fileUtil.extractText(filePath), options);
            cacheResult(cacheKey, fallbackResult);

            // 即使失败也记录任务 - 使用原始文件名
            try {
                recordExtractionTask(studentId, filePath, originalFileName, options, fallbackResult);
            } catch (Exception ex) {
                log.error("记录信息提取任务失败", ex);
            }

            return fallbackResult;
        }
    }

    /**
     * 记录信息提取任务到数据库
     */
    private void recordExtractionTask(Long studentId, String filePath, String originalFileName, ExtractionOptions options, PaperExtractionResult result) {
        try {
            PaperExtractionTask task = new PaperExtractionTask();
            task.setStudentId(studentId);
            task.setFileId(generateFileId(filePath));
            task.setFileName(originalFileName); // 使用原始文件名而不是UUID文件名
            task.setExtractOptions(serializeExtractionOptions(options));
            task.setStatus("COMPLETED");
            task.setExtractResult(serializeExtractionResult(result));
            task.setCreateTime(LocalDateTime.now());
            task.setUpdateTime(LocalDateTime.now());

            paperExtractionTaskMapper.insert(task);
            log.info("信息提取任务记录成功，任务ID: {}, 学生ID: {}, 文件名: {}", task.getId(), studentId, originalFileName);

        } catch (Exception e) {
            log.error("记录信息提取任务失败", e);
            throw new RuntimeException("记录信息提取任务失败: " + e.getMessage());
        }
    }

    /**
     * 生成文件ID
     */
    private String generateFileId(String filePath) {
        String fileName = getFileNameFromPath(filePath);
        return UUID.randomUUID().toString() + "_" + fileName.hashCode();
    }

    /**
     * 从文件路径中提取文件名
     */
    private String getFileNameFromPath(String filePath) {
        if (filePath == null) return "unknown.pdf";
        int lastSlash = filePath.lastIndexOf('/');
        int lastBackslash = filePath.lastIndexOf('\\');
        int lastIndex = Math.max(lastSlash, lastBackslash);
        return lastIndex >= 0 ? filePath.substring(lastIndex + 1) : filePath;
    }

    /**
     * 序列化提取选项
     */
    private String serializeExtractionOptions(ExtractionOptions options) {
        try {
            return objectMapper.writeValueAsString(options);
        } catch (JsonProcessingException e) {
            log.error("序列化提取选项失败", e);
            return "{}";
        }
    }

    /**
     * 序列化提取结果
     */
    private String serializeExtractionResult(PaperExtractionResult result) {
        try {
            return objectMapper.writeValueAsString(result);
        } catch (JsonProcessingException e) {
            log.error("序列化提取结果失败", e);
            return "{}";
        }
    }

    /**
     * 单独提取某项信息 - 优化版
     */
    public PaperExtractionResult extractSingleItem(String filePath, String originalFileName, String itemType, ExtractionOptions options, Long studentId) {
        String cacheKey = generateCacheKey(filePath + "|" + itemType, options);

        if (isCacheValid(cacheKey)) {
            log.info("使用单项目缓存结果，类型: {}", itemType);
            return extractionCache.get(cacheKey);
        }

        try {
            log.info("单独提取 {} 信息，文件路径: {}, 原始文件名: {}, 学生ID: {}", itemType, filePath, originalFileName, studentId);

            String content = fileUtil.extractText(filePath);
            if (content == null || content.trim().isEmpty()) {
                throw new RuntimeException("无法从文件中提取文本内容");
            }

            // 构建针对性的提示词
            String prompt = buildSingleItemPrompt(content, itemType, options);
            String aiResponse = aliBailianService.callQwenModel(prompt);
            PaperExtractionResult result = parseSingleItemResponse(aiResponse, content, itemType);

            log.info("{} 信息提取完成", itemType);

            cacheResult(cacheKey, result);

            // 记录单独提取任务 - 使用原始文件名
            recordSingleExtractionTask(studentId, filePath, originalFileName, itemType, options, result);

            return result;

        } catch (Exception e) {
            log.error("单独提取 {} 信息失败", itemType, e);
            PaperExtractionResult fallbackResult = extractSingleItemFallback(fileUtil.extractText(filePath), itemType);
            cacheResult(cacheKey, fallbackResult);

            // 记录失败的任务 - 使用原始文件名
            try {
                recordSingleExtractionTask(studentId, filePath, originalFileName, itemType, options, fallbackResult);
            } catch (Exception ex) {
                log.error("记录单独提取任务失败", ex);
            }

            return fallbackResult;
        }
    }

    /**
     * 记录单独提取任务
     */
    private void recordSingleExtractionTask(Long studentId, String filePath, String originalFileName, String itemType, ExtractionOptions options, PaperExtractionResult result) {
        try {
            PaperExtractionTask task = new PaperExtractionTask();
            task.setStudentId(studentId);
            task.setFileId(generateFileId(filePath) + "_" + itemType);
            task.setFileName(originalFileName + " [" + itemType + "]"); // 使用原始文件名加上类型后缀

            // 设置特定的提取选项
            ExtractionOptions singleOptions = new ExtractionOptions();
            switch (itemType) {
                case "basicInfo":
                    singleOptions.setExtractBasicInfo(true);
                    break;
                case "keywords":
                    singleOptions.setExtractKeywords(true);
                    break;
                case "abstract":
                    singleOptions.setExtractAbstract(true);
                    break;
                case "references":
                    singleOptions.setExtractReferences(true);
                    break;
            }
            task.setExtractOptions(serializeExtractionOptions(singleOptions));

            task.setStatus("COMPLETED");
            task.setExtractResult(serializeExtractionResult(result));
            task.setCreateTime(LocalDateTime.now());
            task.setUpdateTime(LocalDateTime.now());

            paperExtractionTaskMapper.insert(task);
            log.info("单独提取任务记录成功，任务ID: {}, 类型: {}, 文件名: {}", task.getId(), itemType, originalFileName);

        } catch (Exception e) {
            log.error("记录单独提取任务失败", e);
        }
    }

    // 以下所有原有方法保持不变...

    /**
     * 构建优化的提取提示词
     */
    private String buildOptimizedExtractionPrompt(String content, ExtractionOptions options) {
        StringBuilder prompt = new StringBuilder();

        prompt.append("你是一个专业的学术论文分析助手。请严格按照要求从论文内容中提取信息。\n\n");
        prompt.append("重要要求：\n");
        prompt.append("1. 必须返回纯JSON格式，不要有任何额外文字\n");
        prompt.append("2. 所有字段都必须有值，不能为null或空字符串\n");
        prompt.append("3. 数字字段使用数字类型，不要用字符串\n");
        prompt.append("4. 如果找不到信息，使用合理的默认值\n\n");

        prompt.append("提取字段说明：\n");

        if (options.isExtractBasicInfo()) {
            prompt.append("【基本信息】\n");
            prompt.append("- title: 论文标题（提取文档开头最显著的文字）\n");
            prompt.append("- author: 作者（查找'作者：'、'姓名：'等格式）\n");
            prompt.append("- studentId: 学号（查找'学号：'格式，通常是数字）\n");
            prompt.append("- major: 专业（查找'专业：'、'学院：'等）\n");
            prompt.append("- className: 班级（查找'班级：'、'班'等）\n");
            prompt.append("- supervisor: 指导教师（查找'指导老师：'、'导师：'等）\n");
            prompt.append("- wordCount: 总字数（基于内容计算，只计算中英文字符）\n\n");
        }

        if (options.isExtractKeywords()) {
            prompt.append("【关键词】\n");
            prompt.append("- 提取3-5个最核心的关键词\n");
            prompt.append("- importance: 根据词频和位置判断重要性（high/medium/low）\n");
            prompt.append("- frequency: 在文中出现的准确次数\n\n");
        }

        if (options.isExtractAbstract()) {
            prompt.append("【摘要】\n");
            prompt.append("- chineseAbstract: 中文摘要（查找'摘要：'开头的内容）\n");
            prompt.append("- englishAbstract: 英文摘要（查找'Abstract：'开头的内容）\n\n");
        }

        if (options.isExtractReferences()) {
            prompt.append("【参考文献】\n");
            prompt.append("- 提取10-20条最重要的参考文献\n");
            prompt.append("- 准确识别文献类型：journal(期刊)/book(图书)/conference(会议)/thesis(学位论文)/other(其他)\n");
            prompt.append("- 尽量提取完整的作者、年份、标题、出版社信息\n\n");
        }

        prompt.append("论文内容（前4000字符）：\n");
        String contentPreview = content.length() > 4000 ? content.substring(0, 4000) + "..." : content;
        prompt.append("```text\n");
        prompt.append(contentPreview);
        prompt.append("\n```\n\n");

        prompt.append("返回JSON格式（严格按照这个结构）：\n");
        prompt.append(buildJsonTemplate(options));

        return prompt.toString();
    }

    /**
     * 构建JSON模板
     */
    private String buildJsonTemplate(ExtractionOptions options) {
        StringBuilder json = new StringBuilder();
        json.append("{\n");

        List<String> sections = new ArrayList<>();

        if (options.isExtractBasicInfo()) {
            sections.add("  \"basicInfo\": {\n" +
                    "    \"title\": \"论文标题\",\n" +
                    "    \"author\": \"作者姓名\",\n" +
                    "    \"studentId\": \"学号\",\n" +
                    "    \"major\": \"专业名称\",\n" +
                    "    \"className\": \"班级名称\",\n" +
                    "    \"supervisor\": \"指导教师\",\n" +
                    "    \"wordCount\": 5000\n" +
                    "  }");
        }

        if (options.isExtractKeywords()) {
            sections.add("  \"keywords\": [\n" +
                    "    {\"keyword\": \"关键词1\", \"importance\": \"high\", \"frequency\": 10},\n" +
                    "    {\"keyword\": \"关键词2\", \"importance\": \"medium\", \"frequency\": 5}\n" +
                    "  ]");
        }

        if (options.isExtractAbstract()) {
            sections.add("  \"abstract\": {\n" +
                    "    \"chineseAbstract\": \"这里是中国摘要内容...\",\n" +
                    "    \"englishAbstract\": \"This is English abstract...\"\n" +
                    "  }");
        }

        if (options.isExtractReferences()) {
            sections.add("  \"references\": [\n" +
                    "    {\"title\": \"文献标题\", \"author\": \"作者\", \"year\": 2023, \"type\": \"journal\", \"publisher\": \"期刊名称\"},\n" +
                    "    {\"title\": \"文献标题2\", \"author\": \"作者2\", \"year\": 2022, \"type\": \"book\", \"publisher\": \"出版社\"}\n" +
                    "  ]");
        }

        // 添加统计信息部分
        sections.add("  \"statistics\": {\n" +
                "    \"totalReferences\": 15,\n" +
                "    \"chapterCount\": 5,\n" +
                "    \"figureCount\": 8,\n" +
                "    \"tableCount\": 3\n" +
                "  }");

        json.append(String.join(",\n", sections));
        json.append("\n}");

        return json.toString();
    }

    /**
     * 预处理文本内容
     */
    private String preprocessContent(String content) {
        if (content == null) return "";

        // 移除过多的空白字符
        String processed = content.replaceAll("\\s+", " ");

        // 标准化标点符号
        processed = processed.replaceAll("，", ",")
                .replaceAll("：", ":")
                .replaceAll("；", ";")
                .replaceAll("！", "!")
                .replaceAll("？", "?")
                .replaceAll("（", "(")
                .replaceAll("）", ")")
                .replaceAll("【", "[")
                .replaceAll("】", "]");

        return processed.trim();
    }

    /**
     * 解析AI响应 - 增强版
     */
    private PaperExtractionResult parseAIResponse(String aiResponse, String content) {
        try {
            log.info("开始解析AI响应");

            // 多步骤清理响应文本
            String jsonStr = extractJsonFromResponse(aiResponse);
            log.debug("提取的JSON字符串长度: {}", jsonStr.length());

            // 验证和修复JSON
            jsonStr = validateAndFixJson(jsonStr);

            // 解析JSON
            PaperExtractionResult result = parseJsonResponse(jsonStr);

            log.info("AI响应解析完成");
            return result;

        } catch (Exception e) {
            log.error("解析AI响应失败: {}", e.getMessage());
            throw new RuntimeException("解析AI响应失败: " + e.getMessage());
        }
    }

    /**
     * 解析JSON响应 - 核心方法
     */
    private PaperExtractionResult parseJsonResponse(String jsonStr) throws JsonProcessingException {
        log.debug("开始解析JSON响应");

        if (jsonStr == null || jsonStr.trim().isEmpty()) {
            throw new IllegalArgumentException("JSON字符串为空");
        }

        try {
            // 直接解析JSON
            PaperExtractionResult result = objectMapper.readValue(jsonStr, PaperExtractionResult.class);
            log.debug("JSON解析成功");
            return result;

        } catch (JsonProcessingException e) {
            log.error("JSON解析失败: {}", e.getMessage());
            log.debug("原始JSON字符串: {}", jsonStr);

            // 尝试修复常见的JSON问题
            String fixedJson = fixCommonJsonIssues(jsonStr);
            try {
                PaperExtractionResult result = objectMapper.readValue(fixedJson, PaperExtractionResult.class);
                log.info("使用修复后的JSON解析成功");
                return result;
            } catch (JsonProcessingException e2) {
                log.error("修复后的JSON仍然解析失败: {}", e2.getMessage());
                throw new RuntimeException("JSON解析失败: " + e.getMessage());
            }
        }
    }

    /**
     * 修复常见的JSON问题
     */
    private String fixCommonJsonIssues(String jsonStr) {
        String fixed = jsonStr;

        // 修复尾随逗号
        fixed = fixed.replaceAll(",(\n\\s*[}\\])])", "$1");

        // 修复单引号
        fixed = fixed.replaceAll("'", "\"");

        // 修复未转义的特殊字符
        fixed = fixed.replaceAll("([^\\\\])\"", "$1\\\\\"");

        // 修复缺失的引号
        fixed = fixed.replaceAll("(\\w+):", "\"$1\":");

        return fixed;
    }

    /**
     * 验证和修复JSON
     */
    private String validateAndFixJson(String jsonStr) {
        if (jsonStr == null || jsonStr.trim().isEmpty()) {
            throw new RuntimeException("JSON字符串为空");
        }

        // 基本清理
        String cleaned = jsonStr.trim();

        // 移除可能的markdown标记
        cleaned = cleaned.replaceAll("```json", "").replaceAll("```", "").trim();

        // 确保以{开头，以}结尾
        int start = cleaned.indexOf('{');
        int end = cleaned.lastIndexOf('}');

        if (start == -1 || end == -1 || start >= end) {
            throw new RuntimeException("无效的JSON格式: 缺少大括号");
        }

        cleaned = cleaned.substring(start, end + 1);

        // 修复常见的JSON格式问题
        cleaned = cleaned.replaceAll(",(\n\\s*)}", "$1}") // 移除尾随逗号
                .replaceAll(",\\s*}", "}") // 移除对象尾随逗号
                .replaceAll(",\\s*]", "]"); // 移除数组尾随逗号

        return cleaned;
    }

    /**
     * 从响应中提取JSON - 增强版
     */
    private String extractJsonFromResponse(String response) {
        if (response == null || response.trim().isEmpty()) {
            throw new RuntimeException("AI响应为空");
        }

        // 方法1: 直接解析
        if (response.trim().startsWith("{") && response.trim().endsWith("}")) {
            try {
                objectMapper.readTree(response);
                return response;
            } catch (Exception e) {
                // 继续尝试其他方法
            }
        }

        // 方法2: 查找JSON对象
        Pattern jsonPattern = Pattern.compile("\\{(?:[^{}]|\\{(?:[^{}]|\\{[^{}]*\\})*\\})*\\}", Pattern.DOTALL);
        Matcher matcher = jsonPattern.matcher(response);

        if (matcher.find()) {
            String jsonStr = matcher.group();
            try {
                objectMapper.readTree(jsonStr);
                return jsonStr;
            } catch (Exception e) {
                log.warn("找到的JSON无效，继续尝试");
            }
        }

        // 方法3: 逐层提取
        int start = response.indexOf('{');
        int end = response.lastIndexOf('}');

        if (start >= 0 && end > start) {
            String jsonStr = response.substring(start, end + 1);
            try {
                objectMapper.readTree(jsonStr);
                return jsonStr;
            } catch (Exception e) {
                throw new RuntimeException("无法提取有效的JSON: " + e.getMessage());
            }
        }

        throw new RuntimeException("在响应中找不到有效的JSON");
    }

    /**
     * 后处理结果
     */
    private PaperExtractionResult postProcessResult(PaperExtractionResult result, String content, ExtractionOptions options) {
        // 确保所有必需字段都存在
        if (result == null) {
            result = new PaperExtractionResult();
        }

        // 补全基本信息
        if (options.isExtractBasicInfo()) {
            if (result.getBasicInfo() == null) {
                result.setBasicInfo(new BasicInfo());
            }
            completeBasicInfo(result.getBasicInfo(), content);
        }

        // 补全关键词
        if (options.isExtractKeywords() && (result.getKeywords() == null || result.getKeywords().isEmpty())) {
            result.setKeywords(extractEnhancedKeywords(content));
        }

        // 补全摘要
        if (options.isExtractAbstract() && result.getAbstractInfo() == null) {
            result.setAbstractInfo(extractEnhancedAbstract(content));
        }

        // 补全参考文献
        if (options.isExtractReferences() && (result.getReferences() == null || result.getReferences().isEmpty())) {
            result.setReferences(extractEnhancedReferences(content));
        }

        // 计算统计信息
        if (result.getStatistics() == null) {
            result.setStatistics(calculateEnhancedStatistics(content, result));
        }

        return result;
    }

    /**
     * 增强的备用信息提取
     */
    private PaperExtractionResult extractEnhancedFallbackInfo(String content, ExtractionOptions options) {
        log.info("使用增强备用方法提取信息");

        PaperExtractionResult result = new PaperExtractionResult();

        if (options.isExtractBasicInfo()) {
            result.setBasicInfo(extractEnhancedBasicInfo(content));
        }

        if (options.isExtractKeywords()) {
            result.setKeywords(extractEnhancedKeywords(content));
        }

        if (options.isExtractAbstract()) {
            result.setAbstractInfo(extractEnhancedAbstract(content));
        }

        if (options.isExtractReferences()) {
            result.setReferences(extractEnhancedReferences(content));
        }

        result.setStatistics(calculateEnhancedStatistics(content, result));

        return result;
    }

    /**
     * 增强的基本信息提取
     */
    private BasicInfo extractEnhancedBasicInfo(String content) {
        BasicInfo basicInfo = new BasicInfo();

        basicInfo.setTitle(extractTitleEnhanced(content));
        basicInfo.setAuthor(extractAuthorEnhanced(content));
        basicInfo.setStudentId(extractStudentIdEnhanced(content));
        basicInfo.setMajor(extractMajorEnhanced(content));
        basicInfo.setClassName(extractClassNameEnhanced(content));
        basicInfo.setSupervisor(extractSupervisorEnhanced(content));
        basicInfo.setWordCount(calculateWordCount(content));

        return basicInfo;
    }

    /**
     * 增强的标题提取
     */
    private String extractTitleEnhanced(String content) {
        // 方法1: 提取文档前几行中最可能的标题
        String[] lines = content.split("\n");
        for (int i = 0; i < Math.min(lines.length, 10); i++) {
            String line = lines[i].trim();
            if (isLikelyTitle(line)) {
                return line;
            }
        }

        // 方法2: 查找标题特征
        Pattern titlePattern = Pattern.compile("^(第[一二三四五六七八九十]+章\\s+)?[^。，；！？]{5,50}$");
        for (String line : lines) {
            String trimmed = line.trim();
            if (titlePattern.matcher(trimmed).matches() && trimmed.length() > 10) {
                return trimmed;
            }
        }

        return "论文标题";
    }

    private boolean isLikelyTitle(String text) {
        if (text.length() < 10 || text.length() > 100) return false;
        if (text.contains("摘要") || text.contains("目录") || text.contains("参考文献")) return false;
        if (text.matches(".*[第章节图表].*")) return false;
        return true;
    }

    /**
     * 增强的作者提取
     */
    private String extractAuthorEnhanced(String content) {
        Pattern[] patterns = {
                Pattern.compile("作者[：:\\s]+([^\\n\\d]{2,10})"),
                Pattern.compile("姓名[：:\\s]+([^\\n\\d]{2,10})"),
                Pattern.compile("^([^\\d\\s]{2,5}[\\s]+[^\\d\\s]{2,5})\\s*$", Pattern.MULTILINE)
        };

        for (Pattern pattern : patterns) {
            Matcher matcher = pattern.matcher(content);
            if (matcher.find()) {
                return matcher.group(1).trim();
            }
        }

        return "未知作者";
    }

    /**
     * 增强的学号提取
     */
    private String extractStudentIdEnhanced(String content) {
        Pattern[] patterns = {
                Pattern.compile("学号[：:\\s]+([a-zA-Z0-9]{5,15})"),
                Pattern.compile("student[\\s-]*id[：:\\s]*([a-zA-Z0-9]{5,15})", Pattern.CASE_INSENSITIVE),
                Pattern.compile("\\b(\\d{10,12})\\b")
        };

        for (Pattern pattern : patterns) {
            Matcher matcher = pattern.matcher(content);
            if (matcher.find()) {
                return matcher.group(1).trim();
            }
        }

        return "未知学号";
    }

    /**
     * 增强的专业提取
     */
    private String extractMajorEnhanced(String content) {
        Pattern pattern = Pattern.compile("专业[：:\\s]+([^\\n]{2,20})");
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            return matcher.group(1).trim();
        }
        return "计算机科学与技术";
    }

    /**
     * 增强的班级提取
     */
    private String extractClassNameEnhanced(String content) {
        Pattern pattern = Pattern.compile("班级[：:\\s]+([^\\n\\d]{2,10})");
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            return matcher.group(1).trim();
        }
        return "未知班级";
    }

    /**
     * 增强的指导教师提取
     */
    private String extractSupervisorEnhanced(String content) {
        Pattern[] patterns = {
                Pattern.compile("指导教?师[：:\\s]+([^\\n]{2,10})"),
                Pattern.compile("导师[：:\\s]+([^\\n]{2,10})"),
                Pattern.compile("supervisor[：:\\s]+([^\\n]{2,20})", Pattern.CASE_INSENSITIVE)
        };

        for (Pattern pattern : patterns) {
            Matcher matcher = pattern.matcher(content);
            if (matcher.find()) {
                return matcher.group(1).trim();
            }
        }

        return "未知教师";
    }

    /**
     * 计算准确的字数
     */
    private Integer calculateWordCount(String content) {
        if (content == null) return 0;
        // 只计算中英文字符，排除标点符号和空白
        String cleanContent = content.replaceAll("[\\p{P}\\p{S}\\s]", "");
        return cleanContent.length();
    }

    /**
     * 增强的关键词提取
     */
    private List<Keyword> extractEnhancedKeywords(String content) {
        List<Keyword> keywords = new ArrayList<>();

        // 学术常用关键词库
        String[] academicWords = {
                "人工智能", "机器学习", "深度学习", "神经网络", "数据分析",
                "大数据", "云计算", "物联网", "区块链", "网络安全",
                "算法", "模型", "系统", "设计", "实现",
                "研究", "分析", "优化", "性能", "应用"
        };

        Map<String, Integer> wordFreq = new HashMap<>();
        for (String word : academicWords) {
            int count = countWordOccurrences(content, word);
            if (count > 0) {
                wordFreq.put(word, count);
            }
        }

        // 按频率排序
        wordFreq.entrySet().stream()
                .sorted((a, b) -> b.getValue().compareTo(a.getValue()))
                .limit(5)
                .forEach(entry -> {
                    Keyword keyword = new Keyword();
                    keyword.setKeyword(entry.getKey());
                    keyword.setFrequency(entry.getValue());
                    keyword.setImportance(entry.getValue() > 5 ? "high" : entry.getValue() > 2 ? "medium" : "low");
                    keywords.add(keyword);
                });

        return keywords;
    }

    /**
     * 增强的摘要提取
     */
    private Abstract extractEnhancedAbstract(String content) {
        Abstract abstractInfo = new Abstract();

        // 提取中文摘要
        Pattern chineseAbstractPattern = Pattern.compile("摘要[：:\\s]*([^。]+[。][^。]*)");
        Matcher matcher = chineseAbstractPattern.matcher(content);
        if (matcher.find()) {
            abstractInfo.setChineseAbstract(matcher.group(1).trim());
        } else {
            // 备用方法：提取包含"摘要"的段落
            String[] paragraphs = content.split("\n");
            for (String para : paragraphs) {
                if (para.contains("摘要") && para.length() > 50) {
                    abstractInfo.setChineseAbstract(para.replace("摘要", "").trim());
                    break;
                }
            }
        }

        // 提取英文摘要
        Pattern englishAbstractPattern = Pattern.compile("Abstract[：:\\s]*([^.]+[.][^.]*)", Pattern.CASE_INSENSITIVE);
        matcher = englishAbstractPattern.matcher(content);
        if (matcher.find()) {
            abstractInfo.setEnglishAbstract(matcher.group(1).trim());
        } else {
            abstractInfo.setEnglishAbstract("Abstract not available in the document.");
        }

        return abstractInfo;
    }

    /**
     * 增强的参考文献提取
     */
    private List<Reference> extractEnhancedReferences(String content) {
        List<Reference> references = new ArrayList<>();

        // 查找参考文献章节
        String referenceSection = extractReferenceSection(content);
        if (referenceSection != null) {
            references = parseReferencesFromSection(referenceSection);
        }

        // 如果没找到，使用模式匹配
        if (references.isEmpty()) {
            references = extractReferencesByPattern(content);
        }

        return references.subList(0, Math.min(references.size(), 15));
    }

    private String extractReferenceSection(String content) {
        Pattern refStartPattern = Pattern.compile("参考文献\\s*", Pattern.CASE_INSENSITIVE);
        Matcher matcher = refStartPattern.matcher(content);

        if (matcher.find()) {
            int start = matcher.end();
            // 查找下一个章节标题或文档结束
            Pattern sectionPattern = Pattern.compile("第[一二三四五六七八九十]+章|结论|致谢");
            Matcher sectionMatcher = sectionPattern.matcher(content.substring(start));

            if (sectionMatcher.find()) {
                return content.substring(start, start + sectionMatcher.start());
            } else {
                return content.substring(start);
            }
        }

        return null;
    }

    private List<Reference> parseReferencesFromSection(String section) {
        List<Reference> references = new ArrayList<>();
        String[] lines = section.split("\n");

        for (String line : lines) {
            line = line.trim();
            if (line.length() > 20 && !line.matches("^\\d+\\.?$")) {
                Reference ref = parseReferenceLine(line);
                if (ref != null) {
                    references.add(ref);
                }
            }
        }

        return references;
    }

    private Reference parseReferenceLine(String line) {
        Reference ref = new Reference();
        ref.setTitle(extractReferenceTitle(line));
        ref.setAuthor(extractReferenceAuthor(line));
        ref.setYear(extractReferenceYear(line));
        ref.setType(determineReferenceType(line));
        ref.setPublisher(extractReferencePublisher(line));
        return ref;
    }

    /**
     * 提取参考文献标题 - 增强版
     */
    private String extractReferenceTitle(String line) {
        if (line == null) return "未知标题";

        // 移除作者和年份部分
        String cleanedLine = removeAuthorAndYear(line);

        // 多种标题提取模式
        Pattern[] titlePatterns = {
                // 引号或书名号中的标题
                Pattern.compile("《([^》]+)》|『([^』]+)』|\"([^\"]+)\"|'([^']+)'"),
                // 句号分隔的标题
                Pattern.compile("^[^.]+\\.\\s*([^.,;]+)"),
                // 逗号分隔的标题
                Pattern.compile("^[^,]+,\\s*([^,.;]+)"),
                // 提取较长的连续文字段
                Pattern.compile("([^,.;]{10,100})")
        };

        for (Pattern pattern : titlePatterns) {
            Matcher matcher = pattern.matcher(cleanedLine);
            if (matcher.find()) {
                for (int i = 1; i <= matcher.groupCount(); i++) {
                    if (matcher.group(i) != null) {
                        String title = matcher.group(i).trim();
                        if (isValidTitle(title)) {
                            return title.length() > 100 ? title.substring(0, 100) + "..." : title;
                        }
                    }
                }
            }
        }

        // 最后的手段：提取前100个字符
        String fallbackTitle = cleanedLine.length() > 100 ?
                cleanedLine.substring(0, 100) + "..." : cleanedLine;
        return fallbackTitle.isEmpty() ? "未知标题" : fallbackTitle;
    }

    /**
     * 移除作者和年份部分
     */
    private String removeAuthorAndYear(String line) {
        if (line == null) return "";

        String cleaned = line;

        // 移除常见的作者模式
        cleaned = cleaned.replaceAll("^[^,]{0,50},", "");
        cleaned = cleaned.replaceAll("^[^.]{0,50}\\.", "");

        // 移除年份
        cleaned = cleaned.replaceAll("\\(?(19|20)\\d{2}\\)?", "");

        return cleaned.trim();
    }

    /**
     * 验证标题是否有效
     */
    private boolean isValidTitle(String title) {
        if (title == null || title.trim().isEmpty()) return false;

        String trimmed = title.trim();

        // 长度检查
        if (trimmed.length() < 5 || trimmed.length() > 200) return false;

        // 不能全是数字或符号
        if (trimmed.matches("^[\\d\\s\\p{P}]+$")) return false;

        // 不能包含明显的非标题内容
        if (trimmed.contains("http") ||
                trimmed.contains("DOI") ||
                trimmed.contains("vol.") ||
                trimmed.contains("pp.") ||
                trimmed.matches(".*\\d{1,2}.*\\d{1,2}.*")) {
            return false;
        }

        return true;
    }

    /**
     * 提取参考文献作者 - 增强版
     */
    private String extractReferenceAuthor(String line) {
        if (line == null) return "未知作者";

        // 多种作者提取模式
        Pattern[] authorPatterns = {
                // 中文作者模式：姓名 + 等
                Pattern.compile("^([^,.，。\\d]{2,10}(?:等|,|，|\\s)*)"),
                // 英文作者模式：LastName, F. 或 F. LastName
                Pattern.compile("^([A-Z][a-z]+,\\s*[A-Z]\\.?(?:\\s*&?\\s*[A-Z][a-z]+,\\s*[A-Z]\\.?)*)"),
                // 混合模式：提取第一个逗号前的内容
                Pattern.compile("^([^,，]{2,20})"),
                // 括号中的作者
                Pattern.compile("\\(([^)]+?)\\)"),
                // 作者：模式
                Pattern.compile("(?:作者|by|Author)[：:\\s]*([^,.，]{2,20})")
        };

        for (Pattern pattern : authorPatterns) {
            Matcher matcher = pattern.matcher(line);
            if (matcher.find()) {
                String author = matcher.group(1).trim();
                // 清理作者字符串
                author = cleanAuthorString(author);
                if (isValidAuthor(author)) {
                    return author;
                }
            }
        }

        return "未知作者";
    }

    /**
     * 清理作者字符串
     */
    private String cleanAuthorString(String author) {
        if (author == null) return "";

        String cleaned = author
                .replaceAll("^[\\d\\s\\.]+", "") // 移除开头的数字和点
                .replaceAll("[\\d\\s\\.]+$", "") // 移除结尾的数字和点
                .replaceAll("\\setc\\.?$", "") // 移除etc
                .replaceAll("\\s+", " ") // 合并多个空格
                .trim();

        return cleaned;
    }

    /**
     * 验证作者名称是否有效
     */
    private boolean isValidAuthor(String author) {
        if (author == null || author.trim().isEmpty()) return false;

        String trimmed = author.trim();

        // 长度检查
        if (trimmed.length() < 2 || trimmed.length() > 50) return false;

        // 不能全是数字或符号
        if (trimmed.matches("^[\\d\\s\\p{P}]+$")) return false;

        // 不能包含明显的非作者内容
        if (trimmed.contains("http") ||
                trimmed.contains("DOI") ||
                trimmed.contains("doi") ||
                trimmed.matches(".*\\d{4}.*")) {
            return false;
        }

        return true;
    }

    /**
     * 提取参考文献年份 - 增强版
     */
    private Integer extractReferenceYear(String line) {
        if (line == null) return getCurrentYear();

        // 多种年份提取模式
        Pattern[] yearPatterns = {
                // 标准的4位数字年份
                Pattern.compile("(19|20)\\d{2}"),
                // 带括号的年份
                Pattern.compile("\\((19|20)\\d{2}\\)"),
                // 带点的年份
                Pattern.compile("(19|20)\\d{2}\\."),
                // 逗号后的年份
                Pattern.compile(",\\s*(19|20)\\d{2}"),
                // 中文年份
                Pattern.compile("(\\d{4})年")
        };

        for (Pattern pattern : yearPatterns) {
            Matcher matcher = pattern.matcher(line);
            if (matcher.find()) {
                try {
                    String yearStr = matcher.group(1) != null ? matcher.group(1) + matcher.group(2) : matcher.group(0);
                    int year = Integer.parseInt(yearStr.replaceAll("[^\\d]", ""));
                    // 验证年份合理性
                    if (year >= 1900 && year <= getCurrentYear() + 1) {
                        return year;
                    }
                } catch (NumberFormatException e) {
                    // 继续尝试其他模式
                }
            }
        }

        return getCurrentYear();
    }

    /**
     * 获取当前年份
     */
    private int getCurrentYear() {
        return Calendar.getInstance().get(Calendar.YEAR);
    }

    /**
     * 确定参考文献类型
     */
    private String determineReferenceType(String line) {
        if (line == null) return "other";

        String lowerLine = line.toLowerCase();

        // 期刊论文特征
        if (lowerLine.contains("journal") || lowerLine.contains("刊") ||
                lowerLine.contains("vol.") || lowerLine.contains("volume") ||
                lowerLine.contains("no.") || lowerLine.contains("issue") ||
                lowerLine.matches(".*\\d{4},?\\s*\\d+.*")) {
            return "journal";
        }

        // 会议论文特征
        if (lowerLine.contains("conference") || lowerLine.contains("proc.") ||
                lowerLine.contains("proceedings") || lowerLine.contains("会议") ||
                lowerLine.contains("workshop") || lowerLine.contains("symposium")) {
            return "conference";
        }

        // 学位论文特征
        if (lowerLine.contains("thesis") || lowerLine.contains("dissertation") ||
                lowerLine.contains("学位论文") || lowerLine.contains("硕士") ||
                lowerLine.contains("博士") || lowerLine.contains("毕业论文")) {
            return "thesis";
        }

        // 图书特征
        if (lowerLine.contains("book") || lowerLine.contains("press") ||
                lowerLine.contains("出版社") || lowerLine.contains("出版") ||
                lowerLine.contains("编著") || lowerLine.contains("著") ||
                lowerLine.contains("press")) {
            return "book";
        }

        // 专利特征
        if (lowerLine.contains("patent") || lowerLine.contains("专利")) {
            return "patent";
        }

        // 技术报告特征
        if (lowerLine.contains("report") || lowerLine.contains("技术报告") ||
                lowerLine.contains("technical report")) {
            return "report";
        }

        return "other";
    }

    /**
     * 提取参考文献出版社信息
     */
    private String extractReferencePublisher(String line) {
        if (line == null) return "未知";

        // 常见的出版社模式
        Pattern[] publisherPatterns = {
                // 期刊模式：期刊名 + 年份 + 卷号
                Pattern.compile("(《[^》]+》|[^，,;；]+?)(\\d{4})[^\\d]*(\\d+)"),
                // 出版社模式：出版社 + 出版年
                Pattern.compile("([^，,;；]+?(?:出版社|出版公司|press|publisher))[^\\d]*(\\d{4})"),
                // 简单的出版社名称
                Pattern.compile("(《([^》]+)》|【([^】]+)】|『([^』]+)』)"),
                // 英文期刊名称
                Pattern.compile("([A-Z][a-zA-Z\\s]*(?:Journal|Transactions|Letters|Review))", Pattern.CASE_INSENSITIVE)
        };

        for (Pattern pattern : publisherPatterns) {
            Matcher matcher = pattern.matcher(line);
            if (matcher.find()) {
                for (int i = 1; i <= matcher.groupCount(); i++) {
                    if (matcher.group(i) != null && !matcher.group(i).trim().isEmpty()) {
                        String publisher = matcher.group(i).trim();
                        // 过滤掉明显的非出版社内容
                        if (!publisher.matches(".*\\d.*") &&
                                !publisher.contains("http") &&
                                publisher.length() > 2 &&
                                publisher.length() < 50) {
                            return publisher;
                        }
                    }
                }
            }
        }

        // 备用方法：提取引号或书名号中的内容
        Pattern quotePattern = Pattern.compile("《([^》]+)》|『([^』]+)』|\"([^\"]+)\"|'([^']+)'");
        Matcher quoteMatcher = quotePattern.matcher(line);
        if (quoteMatcher.find()) {
            for (int i = 1; i <= quoteMatcher.groupCount(); i++) {
                if (quoteMatcher.group(i) != null) {
                    return quoteMatcher.group(i).trim();
                }
            }
        }

        // 最后的手段：提取较长的连续文字段
        String[] parts = line.split("[，,;；.。]");
        for (String part : parts) {
            String trimmed = part.trim();
            if (trimmed.length() > 10 && trimmed.length() < 100 &&
                    !trimmed.matches(".*\\d.*") &&
                    !trimmed.contains("http")) {
                return trimmed;
            }
        }

        return "未知";
    }

    private List<Reference> extractReferencesByPattern(String content) {
        List<Reference> references = new ArrayList<>();

        // 匹配常见的参考文献格式
        Pattern refPattern = Pattern.compile("\\[\\d+\\][^\\n]+|\\d+\\.\\s+[^\\n]+");
        Matcher matcher = refPattern.matcher(content);

        int count = 0;
        while (matcher.find() && count < 15) {
            String refLine = matcher.group();
            Reference ref = parseReferenceLine(refLine);
            references.add(ref);
            count++;
        }

        return references;
    }

    /**
     * 增强的统计信息计算
     */
    private Statistics calculateEnhancedStatistics(String content, PaperExtractionResult result) {
        Statistics stats = new Statistics();

        // 参考文献统计
        if (result.getReferences() != null) {
            stats.setTotalReferences(result.getReferences().size());
        } else {
            stats.setTotalReferences(countEnhancedReferences(content));
        }

        // 章节统计
        stats.setChapterCount(countEnhancedChapters(content));

        // 图表统计
        stats.setFigureCount(countEnhancedFigures(content));
        stats.setTableCount(countEnhancedTables(content));

        return stats;
    }

    private int countEnhancedReferences(String content) {
        Pattern refPattern = Pattern.compile("参考文献|References|REFERENCE", Pattern.CASE_INSENSITIVE);
        Matcher matcher = refPattern.matcher(content);
        return (int) matcher.results().count();
    }

    private int countEnhancedChapters(String content) {
        Pattern chapterPattern = Pattern.compile("第[一二三四五六七八九十]+章|Chapter\\s+[\\d]+", Pattern.CASE_INSENSITIVE);
        Matcher matcher = chapterPattern.matcher(content);
        return (int) matcher.results().count();
    }

    private int countEnhancedFigures(String content) {
        Pattern figurePattern = Pattern.compile("图\\s*[\\d\\.]+|Figure\\s*[\\d\\.]+", Pattern.CASE_INSENSITIVE);
        Matcher matcher = figurePattern.matcher(content);
        return (int) matcher.results().count();
    }

    private int countEnhancedTables(String content) {
        Pattern tablePattern = Pattern.compile("表\\s*[\\d\\.]+|Table\\s*[\\d\\.]+", Pattern.CASE_INSENSITIVE);
        Matcher matcher = tablePattern.matcher(content);
        return (int) matcher.results().count();
    }

    /**
     * 统计词频
     */
    private int countWordOccurrences(String content, String word) {
        if (content == null || word == null) return 0;
        int count = 0;
        int index = 0;
        while ((index = content.indexOf(word, index)) != -1) {
            count++;
            index += word.length();
        }
        return count;
    }

    /**
     * 补全基本信息
     */
    private void completeBasicInfo(BasicInfo basicInfo, String content) {
        if (basicInfo.getTitle() == null || basicInfo.getTitle().trim().isEmpty()) {
            basicInfo.setTitle(extractTitleEnhanced(content));
        }
        if (basicInfo.getAuthor() == null || basicInfo.getAuthor().trim().isEmpty()) {
            basicInfo.setAuthor(extractAuthorEnhanced(content));
        }
        if (basicInfo.getStudentId() == null || basicInfo.getStudentId().trim().isEmpty()) {
            basicInfo.setStudentId(extractStudentIdEnhanced(content));
        }
        if (basicInfo.getMajor() == null || basicInfo.getMajor().trim().isEmpty()) {
            basicInfo.setMajor(extractMajorEnhanced(content));
        }
        if (basicInfo.getClassName() == null || basicInfo.getClassName().trim().isEmpty()) {
            basicInfo.setClassName(extractClassNameEnhanced(content));
        }
        if (basicInfo.getSupervisor() == null || basicInfo.getSupervisor().trim().isEmpty()) {
            basicInfo.setSupervisor(extractSupervisorEnhanced(content));
        }
        if (basicInfo.getWordCount() == null || basicInfo.getWordCount() == 0) {
            basicInfo.setWordCount(calculateWordCount(content));
        }
    }

    // 缓存相关方法
    private String generateCacheKey(String filePath, ExtractionOptions options) {
        return filePath + "|" + options.hashCode();
    }

    private boolean isCacheValid(String cacheKey) {
        if (!extractionCache.containsKey(cacheKey)) return false;

        Long timestamp = cacheTimestamps.get(cacheKey);
        if (timestamp == null) return false;

        return System.currentTimeMillis() - timestamp < CACHE_EXPIRY_MS;
    }

    private void cacheResult(String cacheKey, PaperExtractionResult result) {
        extractionCache.put(cacheKey, result);
        cacheTimestamps.put(cacheKey, System.currentTimeMillis());

        // 清理过期缓存
        cleanupExpiredCache();
    }

    private void cleanupExpiredCache() {
        long currentTime = System.currentTimeMillis();
        cacheTimestamps.entrySet().removeIf(entry ->
                currentTime - entry.getValue() > CACHE_EXPIRY_MS
        );
    }

    /**
     * 构建单项目提取提示词
     */
    private String buildSingleItemPrompt(String content, String itemType, ExtractionOptions options) {
        StringBuilder prompt = new StringBuilder();

        prompt.append("你是一个专业的学术论文分析助手。请专注于提取指定的单一信息。\n\n");
        prompt.append("重要要求：\n");
        prompt.append("1. 只返回请求的单一信息，不要提取其他内容\n");
        prompt.append("2. 必须返回纯JSON格式\n");
        prompt.append("3. 确保信息准确完整\n\n");

        prompt.append("提取要求：\n");
        switch (itemType) {
            case "basicInfo":
                prompt.append("只提取论文的基本信息，包括：\n");
                prompt.append("- title: 论文标题\n");
                prompt.append("- author: 作者姓名\n");
                prompt.append("- studentId: 学号\n");
                prompt.append("- major: 专业名称\n");
                prompt.append("- className: 班级名称\n");
                prompt.append("- supervisor: 指导教师\n");
                prompt.append("- wordCount: 总字数\n");
                break;
            case "keywords":
                prompt.append("只提取论文的关键词，3-5个核心关键词\n");
                break;
            case "abstract":
                prompt.append("只提取论文的中英文摘要\n");
                break;
            case "references":
                prompt.append("只提取论文的参考文献，10-15条重要文献\n");
                break;
        }

        prompt.append("\n论文内容预览：\n");
        String contentPreview = content.length() > 3000 ? content.substring(0, 3000) + "..." : content;
        prompt.append("```text\n");
        prompt.append(contentPreview);
        prompt.append("\n```\n\n");

        prompt.append("返回JSON格式：\n");
        switch (itemType) {
            case "basicInfo":
                prompt.append("{\"basicInfo\": {\"title\": \"标题\", \"author\": \"作者\", \"studentId\": \"学号\", \"major\": \"专业\", \"className\": \"班级\", \"supervisor\": \"教师\", \"wordCount\": 5000}}");
                break;
            case "keywords":
                prompt.append("{\"keywords\": [{\"keyword\": \"关键词1\", \"importance\": \"high\", \"frequency\": 10}]}");
                break;
            case "abstract":
                prompt.append("{\"abstract\": {\"chineseAbstract\": \"中文摘要\", \"englishAbstract\": \"英文摘要\"}}");
                break;
            case "references":
                prompt.append("{\"references\": [{\"title\": \"文献标题\", \"author\": \"作者\", \"year\": 2023, \"type\": \"journal\", \"publisher\": \"出版社\"}]}");
                break;
        }

        return prompt.toString();
    }

    /**
     * 解析单项目响应
     */
    private PaperExtractionResult parseSingleItemResponse(String aiResponse, String content, String itemType) {
        try {
            String jsonStr = extractJsonFromResponse(aiResponse);
            PaperExtractionResult result = parseJsonResponse(jsonStr);
            validateAndCompleteSingleResult(result, content, itemType);
            return result;
        } catch (Exception e) {
            log.error("解析单项目AI响应失败: {}", e.getMessage());
            throw new RuntimeException("解析AI响应失败: " + e.getMessage());
        }
    }

    /**
     * 验证和补全单项目结果
     */
    private void validateAndCompleteSingleResult(PaperExtractionResult result, String content, String itemType) {
        switch (itemType) {
            case "basicInfo":
                if (result.getBasicInfo() == null) {
                    result.setBasicInfo(new BasicInfo());
                }
                completeBasicInfo(result.getBasicInfo(), content);
                break;
            case "keywords":
                if (result.getKeywords() == null || result.getKeywords().isEmpty()) {
                    result.setKeywords(extractEnhancedKeywords(content));
                }
                break;
            case "abstract":
                if (result.getAbstractInfo() == null) {
                    result.setAbstractInfo(extractEnhancedAbstract(content));
                }
                break;
            case "references":
                if (result.getReferences() == null || result.getReferences().isEmpty()) {
                    result.setReferences(extractEnhancedReferences(content));
                }
                break;
        }
    }

    /**
     * 单项目备用提取方法
     */
    private PaperExtractionResult extractSingleItemFallback(String content, String itemType) {
        PaperExtractionResult result = new PaperExtractionResult();

        switch (itemType) {
            case "basicInfo":
                result.setBasicInfo(extractEnhancedBasicInfo(content));
                break;
            case "keywords":
                result.setKeywords(extractEnhancedKeywords(content));
                break;
            case "abstract":
                result.setAbstractInfo(extractEnhancedAbstract(content));
                break;
            case "references":
                result.setReferences(extractEnhancedReferences(content));
                break;
        }

        return result;
    }

    // 数据类保持不变
    @lombok.Data
    public static class PaperExtractionResult {
        private BasicInfo basicInfo;
        private List<Keyword> keywords = new ArrayList<>();

        @JsonProperty("abstract")
        private Abstract abstractInfo;

        private List<Reference> references = new ArrayList<>();
        private Statistics statistics;
    }

    @lombok.Data
    public static class BasicInfo {
        private String title;
        private String author;
        private String studentId;
        private String major;
        private String className;
        private String supervisor;
        private Integer wordCount;
    }

    @lombok.Data
    public static class Keyword {
        private String keyword;
        private String importance;
        private Integer frequency;
    }

    @lombok.Data
    public static class Abstract {
        private String chineseAbstract;
        private String englishAbstract;
    }

    @lombok.Data
    public static class Reference {
        private String title;
        private String author;
        private Integer year;
        private String type;
        private String publisher;
    }

    @lombok.Data
    public static class Statistics {
        private Integer totalReferences = 0;
        private Integer chapterCount = 0;
        private Integer figureCount = 0;
        private Integer tableCount = 0;
    }

    @lombok.Data
    public static class ExtractionOptions {
        private boolean extractBasicInfo = true;
        private boolean extractKeywords = true;
        private boolean extractAbstract = true;
        private boolean extractReferences = true;
        private String language = "zh";
    }
}